package com.yunduansing.demo.service.impl;

import com.yunduansing.demo.dao.account.AccountDao;
import com.yunduansing.demo.entity.UserDepartEntity;
import com.yunduansing.demo.entity.UserEntity;
import com.yunduansing.demo.entity.UserPostEntity;
import com.yunduansing.demo.entity.UserRoleEntity;
import com.yunduansing.demo.enums.UserStatus;
import com.yunduansing.demo.exception.MyException;
import com.yunduansing.demo.exception.RecordExistsException;
import com.yunduansing.demo.mapper.UserMapper;
import com.yunduansing.demo.mapper.UserRoleMapper;
import com.yunduansing.demo.model.common.PageRequestModel;
import com.yunduansing.demo.model.common.PageResultModel;
import com.yunduansing.demo.model.user.UserAddModel;
import com.yunduansing.demo.model.user.UserImportModel;
import com.yunduansing.demo.model.user.UserPageModel;
import com.yunduansing.demo.model.user.UserPageRequestModel;
import com.yunduansing.demo.service.UserDepartService;
import com.yunduansing.demo.service.UserPostService;
import com.yunduansing.demo.service.UserRoleService;
import com.yunduansing.demo.service.UserService;
import com.yunduansing.demo.service.DepartService;
import com.yunduansing.demo.service.DictionaryService;
import com.yunduansing.demo.service.PostService;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.SelectList;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import antlr.StringUtils;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import cn.hutool.json.JSONUtil;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yunduansing
 * @since 2020-05-24
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {
    @Autowired
    private UserMapper mapper;
    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private AuthUserService authUserService;
    @Autowired
    private UserPostService userPostService;
    @Autowired
    private UserDepartService userDepartService;
    @Autowired
    private DictionaryService dictionaryService;
    @Autowired
    private DepartService departService;
    @Value("${user.password}")
    private String initPwd;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean create(UserAddModel model) throws RecordExistsException {
        var account=createAccount(model.getUser().getFullName());
        // var existsData = mapper.findExistsByAccount(model.getUser().getAccount());
        // if (existsData.size() > 0)
        //     throw new RecordExistsException("账号已存在。");
        model.getUser().setPassword(authUserService.encryptPassword(initPwd));
        var user=model.getUser();
        user.setLeaved(false);
        user.setCreateDate(LocalDateTime.now());
        save(user);
        List<UserDepartEntity> departs = new ArrayList<>();
        for (Integer i : model.getDeparts()) {
            departs.add(new UserDepartEntity(user.getId(), i));
        }

        List<UserPostEntity> posts=new ArrayList<>();
        for (Integer i : model.getPosts()) {
            posts.add(new UserPostEntity(i,user.getId(), true));
        }

        userPostService.saveBatch(posts);
        userDepartService.saveBatch(departs);
        return true;
    }

    @Override
    public PageResultModel<UserPageModel> getPage(UserPageRequestModel model) {
        // if(!StrUtil.isBlank(model.getSorter())){
        //     var obj=JSONUtil.toBean(model.getSorter(), Map.class);
        //     model.setSorterMap(obj);
        // }
        Page page=PageHelper.startPage(model.getCurrent(), model.getPageSize(),true);
        var data=mapper.getPage(model);
        if(data.size()>0){
            var userIds=data.stream().map(m->m.getId()).collect(Collectors.toList());
            var userDeparts=mapper.getDepartsByUserId(userIds);
            var userPosts=userPostService.getPostIdsByUserIds(userIds);
            data.stream().forEach(a->{
                var deps=userDeparts.stream().filter(m->m.getUserId()==a.getId()).collect(Collectors.toList());
                a.setDepartName(deps.stream().map(x->x.getDepartName()).collect(Collectors.joining(",")));
                a.setDepartIds(deps.stream().map(x->x.getDepartId()).collect(Collectors.toList()));
                a.setPostIds(userPosts.stream().filter(x->x.getUserId()==a.getId()).map(x->x.getPostId()).collect(Collectors.toList()));
            });
        }
        return new PageResultModel<UserPageModel>(page.getTotal(), data);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(UserAddModel model)  throws RecordExistsException{
        var existsData = mapper.findExistsByAccount(model.getUser().getAccount());
        // if (existsData.stream().filter(x->x.getAccount()==model.getUser().getAccount()&&x.getId()!=model.getUser().getId()).count()>0)
        //     throw new RecordExistsException("账号已存在。");
        
        var user=model.getUser();
        updateById(user);
        List<UserDepartEntity> departs = new ArrayList<>();
        for (Integer i : model.getDeparts()) {
            departs.add(new UserDepartEntity(user.getId(), i));
        }

        List<UserPostEntity> posts=new ArrayList<>();
        for (Integer i : model.getPosts()) {
            posts.add(new UserPostEntity(i,user.getId(), true));
        }
        var map=new HashMap<String,Object>();
        map.put("user_id",user.getId());
        userPostService.removeByMap(map);
        userDepartService.removeByMap(map);
        userPostService.saveBatch(posts);
        userDepartService.saveBatch(departs);
        return true;
    }

    @Override
    public UserPageModel getDetailById(int id) {
        var user=getById(id);
        if(user==null) return null;
        user.setPassword("");
        UserPageModel result=new UserPageModel();//=(UserPageModel)user;
        BeanUtils.copyProperties(user, result);
        
        //所有的字典
        var dic=dictionaryService.getAll();
        //学历
        var edu=dic.stream().filter(x->x.getKey().equals(result.getEducation())).collect(Collectors.toList());
        if(edu.size()>0){
            result.setEducationName(edu.get(0).getValue());
        }
        //政治面貌
        var politic=dic.stream().filter(x->x.getKey().equals(result.getPolitical())).collect(Collectors.toList());
        if(politic.size()>0){
            result.setEducationName(politic.get(0).getValue());
        }
        //婚姻
        var marital=dic.stream().filter(x->x.getKey().equals(result.getMaritalStatus())).collect(Collectors.toList());
        if(marital.size()>0){
            result.setEducationName(marital.get(0).getValue());
        }
        //户籍类型
        var household=dic.stream().filter(x->x.getKey().equals(result.getHouseholdType())).collect(Collectors.toList());
        if(household.size()>0){
            result.setEducationName(household.get(0).getValue());
        }
        //民族
        var ethnicity=dic.stream().filter(x->x.getKey().equals(result.getEthnicity())).collect(Collectors.toList());
        if(ethnicity.size()>0){
            result.setEducationName(ethnicity.get(0).getValue());
        }
        return result;
    }

    @Transactional
    @Override
    public boolean importData(List<UserImportModel> data) {
        //获取所有字典
        var dic=dictionaryService.getAll();
        var users=new ArrayList<UserEntity>();
        var depdata=new ArrayList<UserDepartEntity>();
        data.forEach(x->{
            var userItem=new UserEntity();
            var account=createAccount(x.getFullName());
            userItem.setAccount(account);
            userItem.setBirth(x.getBirth());
            userItem.setCreateDate(LocalDateTime.now());
            //获取学历
            var edu=dic.stream().filter(m->m.getValue().equals(x.getEducation())).findFirst();
            if(!edu.isEmpty()){
                userItem.setEducation(edu.get().getKey());
            }
            userItem.setFullName(x.getFullName());
            //获取民族
            var eth=dic.stream().filter(m->m.getValue().equals(x.getEthnicity())).findFirst();
            if(!edu.isEmpty()){
                userItem.setEthnicity(eth.get().getKey());
            }
            if(!StrUtil.isBlank(x.getGender())){
                userItem.setSex(x.getGender()=="男"?true:false);
            }
            userItem.setJoinDate(x.getJoinDate());
            
            if(!StrUtil.isBlank(x.getDepart())){
                //所有的部门
                var deps=departService.getAll();  
                var depList= x.getDepart().split("、");  
                for(var item:depList){
                    var depItem=deps.stream().filter(m->m.getName().equals(item)).findFirst(); 
                    depdata.add(new UserDepartEntity(1, depItem.get().getId())) ;  
                }
                                                                               
            }
            users.add(userItem);
        });
        //saveBatch(users);//批量保存
        //userDepartService.saveBatch(depdata);
        return false;
    }

    @Override
    public boolean resetPassword(String username, String oldPassword, String newPassword) throws MyException {
        var queryWrapper=new QueryWrapper<UserEntity>();
        queryWrapper.eq("account", username);
        var user=getOne(queryWrapper);
        if(user==null) throw new RecordExistsException("用户不存在。");
        if(!authUserService.validatePassword(oldPassword, user.getPassword())){
            throw new MyException("原密码不对。");
        }
        user.setPassword(authUserService.encryptPassword(newPassword));
        
        return updateById(user);
    }

    @Override
    public String createAccount(String fullName) {
        var username=PinyinUtil.getPinyin(fullName);
        var existsUsers=mapper.selectList(new QueryWrapper<UserEntity>().lambda().like(UserEntity::getAccount, username));
        if(existsUsers.size()==0) return username;
        return username+(existsUsers.size()+1);
    }

    @Override
    public boolean initPassword(List<Integer> userIds) {
        List<UserEntity> users=new ArrayList<>();
        userIds.forEach(x->{
            var item=new UserEntity();
            item.setId(x);
            item.setPassword(authUserService.encryptPassword(initPwd));
            users.add(item);
        });
        return updateBatchById(users);
    }
}
